//
// Created by 78472 on 2023/3/4.
//

#ifndef EXHIBITION_SITEMANAGER_H
#define EXHIBITION_SITEMANAGER_H

#include <thread>
#include <condition_variable>
#include "qlibc/QData.h"
#include "log/Logging.h"
#include "../param.h"
#include "siteService/service_site_manager.h"
#include "common/httpUtil.h"
#include "deviceManager.h"
#include "groupManager.h"

using namespace std;

class siteManager {
private:
    //设备类站点、列表更新
    bool updateComplete{true};
    mutex updateMutex;
    condition_variable updateCv;

    //在线面板列表更新
    std::map<string, qlibc::QData> esp32PanelMap;    //mac-panelData
    std::map<string, int> esp32PanelCoutMap;    //mac-count
    qlibc::QData panelListData;
    bool onlinePanelListUpdate{true};
    mutex panelListMutex;
    condition_variable panelListCv;

    //全局更新标志
    bool devGrpUpdateComplete{false};
    bool panListUpdateComplete{false};
    mutex dgpMutex;
    condition_variable dgpCv;


    //3个后台线程
    std::thread updateDevSitesThread;
    std::thread updateOnlinePanelThread;
    std::thread updateEsp32PanelThread;
    std::thread allCompleteThread;

    //自动更新信息
    siteManager(){
        updateSite();
        updatePanelList();
        updateDevSitesThread = thread([this]{
            updateDevSitesThreadFunc();
        });
        updateOnlinePanelThread = thread([this]{
            updateOnlinePanelThreadFunc();
        });
        allCompleteThread = thread([this]{
            allCompleteThreadFunc();
        });
        updateEsp32PanelThread = thread([this]{
            updateEsp32PanelThreadFunc();
        });
    }

    static siteManager* Instance;

public:
    static siteManager* getInstance(){
        if(Instance == nullptr){
            Instance = new siteManager();
        }
        return Instance;
    }
   
    //更新设备类站点例程
    void updateDevSitesThreadFunc();

    //更新在线面板列表例程
    void updateOnlinePanelThreadFunc();

    //全部更新完毕例程
    void allCompleteThreadFunc();
    
    //从配置站点获取电话号码
    string getPanelPhone();

    //构建device_id
    string buildDeviceId(string deviceMac);

    //获取指定面板所有站点列表
    bool get_all_local_sites(string siteIP, std::set<string>& siteIdSet);

    //构造获取到的设备类站点列表
    bool get_devSites(std::set<string> deviceSiteSet, qlibc::QData response, std::map<string, Json::Value>& sitesMap);

     //更新设备类站点记录
    void update_devSites_record(std::map<string, Json::Value> sitesMap);

    //遍历设备类站点列表，向站点订阅相应的消息
    bool subscribe_devSites_message(std::set<string> siteNames);

    
    //用面板列表修正设备列表、组列表
    void amendDevGrpList_with_panelList(qlibc::QData& device_list, qlibc::QData& group_list, qlibc::QData& panel_list);

    //更新设备类站点、设备列表、组列表
    bool updateSite();

    //更新在线面板列表
    bool updatePanelList();

    //触发站点更新
    void trigger_updateSite();

    //触发面板列表更新
    void trigger_updatePanelList();

     //获取设备类站点
    qlibc::QData getPanelList();

    //组合panelList、deviceList、groupList
    qlibc::QData getAllDeviceInfo();
};


#endif //EXHIBITION_SITEMANAGER_H
